package org.jeecg.modules.car.controller;


import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.SsoUtil;
import org.jeecg.enums.car.CarOrderTypeEnum;
import org.jeecg.model.car.reqvo.CarDayReportReqVo;
import org.jeecg.model.car.respvo.CarDayReportRespVo;
import org.jeecg.modules.car.service.ICarDerateDetailsService;
import org.jeecg.modules.car.service.ICarMerchantOrderService;
import org.jeecg.modules.car.service.ICarOrderService;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Description: 车辆日报表
 * @Author: liurui
 * @Date:   2020-11-26
 * @Version: V1.0
 */
@Slf4j
@Api(tags = "车辆日报表")
@RestController
@RequestMapping("/b/car/dayReport")
public class CarDayReportController {

    @Autowired
    private ICarOrderService carOrderService;

    @Autowired
    private ICarMerchantOrderService carMerchantOrderService;

    @Autowired
    private ICarDerateDetailsService carDerateDetailsService;


    @AutoLog(value = "车场日收款报表-列表查询")
    @ApiOperation(value = "车场日收款报表-列表查询", notes = "车场日收款报表-列表查询")
    @GetMapping(value = "/list")
    public Result<List<CarDayReportRespVo>> queryPageList(CarDayReportReqVo carDayReportReqVo, HttpServletRequest req) {
        log.info("车场日收款报表-列表查询接受参数:{}",carDayReportReqVo);
        Result<List<CarDayReportRespVo>> result = new Result<List<CarDayReportRespVo>>();
        List<CarDayReportRespVo> allList = getCarDayReportRespVoList(carDayReportReqVo);
        result.setSuccess(true);
        result.setResult(allList);
        return result;
    }

    private List<CarDayReportRespVo> getCarDayReportRespVoList(CarDayReportReqVo carDayReportReqVo) {
        List<CarDayReportRespVo> allList = new LinkedList<>();
        if (carDayReportReqVo.getSearchStartTime() == null){
            carDayReportReqVo.setSearchStartTime(DateUtils.getDateStart(new Date()));
        }
        if (carDayReportReqVo.getSearchEndTime() == null ){
            carDayReportReqVo.setSearchEndTime(DateUtils.getDateEnd(new Date()));
        }
        //获取月卡车缴费统计
        carDayReportReqVo.setOrderType(CarOrderTypeEnum.ORDER_TYPE_MONTHS.getCode());
        carDayReportReqVo.setTenantId(SsoUtil.getLoginUser().getTenantId());
        List<CarDayReportRespVo> monthsOrderList = carOrderService.findGroupList(carDayReportReqVo);
        //将列表转成 日期 - 数据对象格式  即 2020-01-01  - 月卡车统计对象
        // 目的:查询出来的结果可能某个日期没有数据,需要和整个查询日期期间比较将没有的日期找出来,设置一个空对象进去
        Map<String,CarDayReportRespVo> monthsOrderMap = new LinkedHashMap<>();
        if (monthsOrderList.size() > 0){
            monthsOrderMap = monthsOrderList.stream().collect(Collectors.toMap(CarDayReportRespVo::getCoverDate, Function.identity()));
        }
        //获取临停车缴费统计
        carDayReportReqVo.setOrderType(CarOrderTypeEnum.ORDER_TYPE_TEMP.getCode());
        List<CarDayReportRespVo> tempOrderList = carOrderService.findGroupList(carDayReportReqVo);
        Map<String,CarDayReportRespVo> tempOrderMap = new LinkedHashMap<>();
        if (tempOrderList.size() > 0){
            tempOrderMap = tempOrderList.stream().collect(Collectors.toMap(CarDayReportRespVo::getCoverDate, Function.identity()));
        }
        // 获取优惠券 - 目前优惠券只能用在临停车上
        List<CarDayReportRespVo> derateOrderList =  carDerateDetailsService.findGroupList(carDayReportReqVo);
        Map<String,CarDayReportRespVo> derateOrderMap = new LinkedHashMap<>();
        if (derateOrderList.size() > 0){
            derateOrderMap = derateOrderList.stream().collect(Collectors.toMap(CarDayReportRespVo::getCoverDate, Function.identity()));
        }
        //获取商户充值统计
        List<CarDayReportRespVo> merchantOrderList  = carMerchantOrderService.findGroupList(carDayReportReqVo);
        Map<String,CarDayReportRespVo> merchantOrderMap = new LinkedHashMap<>();
        if (merchantOrderList.size() > 0){
            merchantOrderMap = merchantOrderList.stream().collect(Collectors.toMap(CarDayReportRespVo::getCoverDate, Function.identity()));
        }
        Set<String> allSetDate = new LinkedHashSet<>();
        while (carDayReportReqVo.getSearchEndTime().compareTo(carDayReportReqVo.getSearchStartTime()) >= 0 ){
            allSetDate.add(DateUtils.date2Str(carDayReportReqVo.getSearchStartTime(),DateUtils.date_sdf));
            carDayReportReqVo.setSearchStartTime(DateUtils.addDate(carDayReportReqVo.getSearchStartTime(),1));
        }
        Iterator<String> it = allSetDate.iterator();
        //合计
        CarDayReportRespVo totalVo = new CarDayReportRespVo("合计","-",null);
        while (it.hasNext()) {
            String tempDate = it.next();
            CarDayReportRespVo monthsVo = monthsOrderMap.get(tempDate);
            if (monthsVo == null) {
                monthsVo = new CarDayReportRespVo(carDayReportReqVo.getParkName(),"月租车",tempDate);
            } else {
                monthsVo.setParkName(carDayReportReqVo.getParkName());
            }
            calculateTotal(totalVo, monthsVo); //计算合计
            allList.add(monthsVo);
            CarDayReportRespVo tempVo = tempOrderMap.get(tempDate);
            if (tempVo == null) {
                tempVo = new CarDayReportRespVo(carDayReportReqVo.getParkName(),"临停车",tempDate);
            }else {
                tempVo.setParkName(carDayReportReqVo.getParkName());
            }
            //临停车需要把优惠券抵扣统计进去
            CarDayReportRespVo derateVo =  derateOrderMap.get(tempDate);
            if (derateVo != null){
                tempVo.setDisCount(derateVo.getDisCount().add(tempVo.getDisCount()));
                tempVo.setSubTotal(derateVo.getDisCount().add(tempVo.getSubTotal()));
            }
            calculateTotal(totalVo, tempVo); //计算合计
            allList.add(tempVo);
            CarDayReportRespVo merchantVo = merchantOrderMap.get(tempDate);
            if (merchantVo == null) {
                merchantVo = new CarDayReportRespVo(carDayReportReqVo.getParkName(),"商户充值",tempDate);
            }else {
                merchantVo.setParkName(carDayReportReqVo.getParkName());
            }
            calculateTotal(totalVo, merchantVo); //计算合计
            allList.add(merchantVo);
        }
        allList.add(totalVo);
        return allList;
    }

    /**
     * 计算合计
     * @param totalVo
     * @param subVo
     */
    private void calculateTotal(CarDayReportRespVo totalVo, CarDayReportRespVo subVo) {
        totalVo.setXianJin(totalVo.getXianJin().add(subVo.getXianJin()));
        totalVo.setZhuanZhang(totalVo.getZhuanZhang().add(subVo.getZhuanZhang()));
        totalVo.setWeixinpayOffline(totalVo.getWeixinpayOffline().add(subVo.getWeixinpayOffline()));
        totalVo.setAlipayOffline(totalVo.getAlipayOffline().add(subVo.getAlipayOffline()));
        totalVo.setPos(totalVo.getPos().add(subVo.getPos()));
        totalVo.setScanOffline(totalVo.getScanOffline().add(subVo.getScanOffline()));
        totalVo.setWeixinpay(totalVo.getWeixinpay().add(subVo.getWeixinpay()));
        totalVo.setAlipay(totalVo.getAlipay().add(subVo.getAlipay()));
        totalVo.setDisCount(totalVo.getDisCount().add(subVo.getDisCount()));
        totalVo.setSubTotal(totalVo.getSubTotal().add(subVo.getSubTotal()));
    }

    /**
     * 导出excel
     *
     * @param carDayReportReqVo
     */
    @AutoLog(value = "车场日收款报表-列表导出")
    @ApiOperation(value = "车场日收款报表-列表导出", notes = "车场日收款报表-列表导出")
    @RequestMapping(value = "/exportXls")
    public ModelAndView exportXls(CarDayReportReqVo carDayReportReqVo) {
        // Step.1 组装查询条件
        LoginUser user = SsoUtil.getLoginUser();
        List<CarDayReportRespVo> allList = getCarDayReportRespVoList(carDayReportReqVo);
        //Step.2 AutoPoi 导出Excel
        ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
        //导出文件名称
        mv.addObject(NormalExcelConstants.FILE_NAME, "车场日收款报表");
        mv.addObject(NormalExcelConstants.CLASS, CarDayReportRespVo.class);
        mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("车场日收款报表("+ carDayReportReqVo.getParkName() +")", "导出人:" + user.getRealname(), "导出信息"));
        mv.addObject(NormalExcelConstants.DATA_LIST, allList);
        return mv;
    }

}
